/* bootpackのメイン */

#include "bootpack.h"
#include <stdio.h>

struct BOOTINFO* binfo = (struct BOOTINFO*)ADR_BOOTINFO;
char keybuf[32], mousebuf[128];
int mx, my, i;
unsigned int memtotal;
struct MOUSE_DEC mdec;
struct MEMMAN* memman = (struct MEMMAN*)MEMMAN_ADDR;
struct SHTCTL* shtctl;
struct SHEET* sht_back, * sht_mouse, * sht_win, * sht_winB, * sht_winC, * sht_winD;
unsigned char* buf_back, buf_mouse[256], * buf_win, * buf_winB, * buf_winC, * buf_winD;
struct TSS32 *tssa, *tssb, *tssc, *tssd;
int a, b, c, d;
//初始化TSS
struct SEGMENT_DESCRIPTOR* gdt = (struct SEGMENT_DESCRIPTOR*)ADR_GDT;
struct GATE_DESCRIPTOR* idt = (struct GATE_DESCRIPTOR*)ADR_IDT;
struct TimeUser* task;


void BMain(void)
{
	//load_tr(3 * 8);
	//far_jump(0, 5 * 8);
	char s[100];
	int count = 99, cnt = 0;
	sht_winB = sheet_alloc(shtctl);
	buf_winB = (unsigned char*)memman_alloc_4k(memman, 160 * 52);
	sheet_setbuf(sht_winB, buf_winB, 160, 52, -1); /* 没有透明色 */
	sheet_slide(sht_winB, mx + 250 - 160, my - 150);
	make_window8(buf_winB, 160, 52, "MainB");
	sheet_updown(sht_winB, 1);

	for (;;)
	{
		count++; /* 从这里开始 */
		sprintf(s, "%010d", count);
		boxfill8(buf_winB, 160, COL8_C6C6C6, 40, 28, 119, 43);
		putfonts8_asc(buf_winB, 160, 40, 28, COL8_000000, s);
		sheet_refresh(sht_winB, 40, 28, 120, 44); /* 到这里结束 */
		sprintf(s, "B EIP:%d EAX:%d EBX:%d ESP:%d", tssb->eip, tssb->eax, tssb->ebx, tssb->esp);
		boxfill8(buf_back, binfo->scrnx, COL8_008484, 10, 240, binfo->scrnx, 260);
		putfonts8_asc(buf_back, binfo->scrnx, 10, 240, COL8_FFFFFF, s);
		sheet_refresh(sht_back, 10, 240, binfo->scrnx, 260); /* 刷新文字 */
		far_jump(0, 5 * 8);
	}
}

void CMain(void)
{
	char s[100];
	int count = 0;
	sht_winC = sheet_alloc(shtctl);
	buf_winC = (unsigned char*)memman_alloc_4k(memman, 160 * 52);
	sheet_setbuf(sht_winC, buf_winC, 160, 52, -1); /* 没有透明色 */
	sheet_slide(sht_winC, mx + 250 - 160, my);
	make_window8(buf_winC, 160, 52, "MainC");
	sheet_updown(sht_winC, 1);
	for (;;)
	{
		count++; /* 从这里开始 */
		sprintf(s, "%010d", count);
		boxfill8(buf_winC, 160, COL8_C6C6C6, 40, 28, 119, 43);
		putfonts8_asc(buf_winC, 160, 40, 28, COL8_000000, s);
		sheet_refresh(sht_winC, 40, 28, 120, 44); /* 到这里结束 */
		sprintf(s, "C EIP:%d EAX:%d EBX:%d ESP:%d", tssc->eip, tssc->eax, tssc->ebx, tssc->esp);
		boxfill8(buf_back, binfo->scrnx, COL8_008484, 10, 220, binfo->scrnx, 240);
		putfonts8_asc(buf_back, binfo->scrnx, 10, 220, COL8_FFFFFF, s);
		sheet_refresh(sht_back, 10, 220, binfo->scrnx, 240); /* 刷新文字 */
		far_jump(0, 6 * 8);
	}
}

void DMain(void)
{
	char s[100];
	int count = 0;
	sht_winD = sheet_alloc(shtctl);
	buf_winD = (unsigned char*)memman_alloc_4k(memman, 160 * 52);
	sheet_setbuf(sht_winD, buf_winD, 160, 52, -1); /* 没有透明色 */
	sheet_slide(sht_winD, mx + 250 - 160, my + 200);
	make_window8(buf_winD, 160, 52, "MainD");
	sheet_updown(sht_winD, 1);
	
	for (;;)
	{
		++count; /* 从这里开始 */
		sprintf(s, "%010d", count);
		boxfill8(buf_winD, 160, COL8_C6C6C6, 40, 28, 119, 43);
		putfonts8_asc(buf_winD, 160, 40, 28, COL8_000000, s);
		sheet_refresh(sht_winD, 40, 28, 120, 44); /* 到这里结束 */
		sprintf(s, "D EIP:%d EAX:%d EBX:%d ESP:%d", tssd->eip, b, c, d);
		boxfill8(buf_back, binfo->scrnx, COL8_008484, 10, 280, binfo->scrnx, 300);
		putfonts8_asc(buf_back, binfo->scrnx, 10, 280, COL8_FFFFFF, s);
		sheet_refresh(sht_back, 10, 280, binfo->scrnx, 300); /* 刷新文字 */
		int se = 0, is = 0, js = 0;
		
		far_jump(0, 3 * 8);
	}
}

void initTSS()
{
	tssa = 0x1520;
	tssb = 0x1C9C;
	tssc = 0x240c;
	tssd = 0x2b80;
	tssa->ldtr = tssb->ldtr = tssc->ldtr = tssd->ldtr = 0;
	tssa->iomap = tssb->iomap = tssc->iomap = tssd->iomap = 0x40000000;
	set_segmdesc(gdt + 3, 103, tssa, AR_TSS32);
	set_segmdesc(gdt + 4, 103, tssb, AR_TSS32);
	set_segmdesc(gdt + 5, 103, tssc, AR_TSS32);
	set_segmdesc(gdt + 6, 103, tssd, AR_TSS32);

	char s[100];
	
	boxfill8(buf_back, binfo->scrnx, COL8_008484, 10, 200, binfo->scrnx, 220);
	putfonts8_asc(buf_back, binfo->scrnx, 10, 200, COL8_FFFFFF, s);
	sheet_refresh(sht_back, 10, 200, binfo->scrnx, 220); /* 刷新文字 */

	load_tr(3 * 8);
	tssb->eip = (int)&BMain;
	tssb->eflags = 0x00000202;
	tssb->eax = tssb->ecx = tssb->ecx = tssb->edx = tssb->ebx = tssb->esp = tssb->ebp = 0;
	tssb->esi = tssb->edi = 0;
	tssb->es = tssb->cs = tssb->ds = tssb->ss = tssb->fs = tssb->gs = 1 * 8;
	b = tssb->esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 8;
	tssb->cs = 2 * 8;

	tssc->eip = (int)&CMain;
	tssc->eflags = 0x00000202;
	tssc->eax = tssc->ecx = tssc->ecx = tssc->edx = tssc->ebx = tssc->esp = tssc->ebp = 0;
	tssc->esi = tssc->edi = 0;
	tssc->es = tssc->cs = tssc->ds = tssc->ss = tssc->fs = tssc->gs = 1 * 8;
	c = tssc->esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 8;
	tssc->cs = 2 * 8;

	tssd->eip = (int)&DMain;
	tssd->eflags = 0x00000202;
	tssd->eax = tssd->ecx = tssd->ecx = tssd->edx = tssd->ebx = tssd->esp = tssd->ebp = 0;
	tssd->esi = tssd->edi = 0;
	d = tssd->es = tssd->cs = tssd->ds = tssd->ss = tssd->fs = tssd->gs = 1 * 8;
	tssd->esp = memman_alloc_4k(memman, 64 * 1024) + 64 * 1024 - 8;
	tssd->cs = 2 * 8;
}
void make_window8(unsigned char* buf, int xsize, int ysize, char* title);



void HariMain(void)
{
	int count = 0;
	char s[100];
	init_gdtidt();
	init_pic();
	
	memtotal = memtest(0x00400000, 0xbfffffff);
	memman_init(memman);
	memman_free(memman, 0x00010000, 0x0009e000); /* 0x00001000 - 0x0009efff */
	memman_free(memman, 0x00400000, memtotal - 0x00400000);
	initTSS();
	io_sti(); /* IDT/PIC的初始化已经完成，于是开放CPU的中断 */
	
	fifo8_init(&keyfifo, 32, keybuf);
	fifo8_init(&mousefifo, 128, mousebuf);
	init_pit();
	io_out8(PIC0_IMR, 0xf8); /* 开放PIC1和键盘中断(11111000) */
	io_out8(PIC1_IMR, 0xef); /* 开放鼠标中断(11101111) */

	init_keyboard();
	enable_mouse(&mdec);

	
	init_palette();
	initTimeUsrCtl();
	task = malloc_timer(20);
	struct TimeUser* affair1 = malloc_timer(3000);// , * affair2 = malloc_timer(10000);
	char affair1Buf[100];
	struct FIFO8 for1, taskF;
	fifo8_init(&for1, 100, affair1Buf);
	set_timer(affair1, 'a', &for1);
	char taskBuf[100];
	fifo8_init(&taskF, 100, taskBuf);
	set_timer(task, 't', &taskF);
	//===================================================================================
	shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny);
	sht_back  = sheet_alloc(shtctl);
	sht_mouse = sheet_alloc(shtctl);
	sht_win = sheet_alloc(shtctl);
	buf_back  = (unsigned char *) memman_alloc_4k(memman, binfo->scrnx * binfo->scrny);
	buf_win = (unsigned char *) memman_alloc_4k(memman, 160 * 52);
	sheet_setbuf(sht_back, buf_back, binfo->scrnx, binfo->scrny, -1); /* 没有透明色 */
	sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 99); /* 透明色号99 */
	sheet_setbuf(sht_win, buf_win, 160, 52, -1); /* 没有透明色 */
	init_screen8(buf_back, binfo->scrnx, binfo->scrny);
	init_mouse_cursor8(buf_mouse, 99); /* 背景色号99 */
	make_window8(buf_win, 160, 52, "MainA");
	sheet_slide(sht_back, 0, 0);
	mx = (binfo->scrnx - 16) / 2; /* 按显示在画面中央来计算坐标 */
	my = (binfo->scrny - 28 - 16) / 2;
	sheet_slide(sht_mouse, mx, my);
	sheet_slide(sht_win, mx - 50, my - 150); 
	sheet_updown(sht_back,  0);
	sheet_updown(sht_win, 1);
	sheet_updown(sht_mouse, 99);
	sprintf(s, "(%3d, %3d)", mx, my);
	putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s);
	sprintf(s, "memory %dMB free : %dKB", memtotal / (1024 * 1024), memman_total(memman) / 1024);
	putfonts8_asc(buf_back, binfo->scrnx, 0, 32, COL8_FFFFFF, s);
	sprintf(s, "shtctl origin:%04X, CTL_NOW:%04X, CTL_VALUE:%04X", shtctl, CTL_NOW, *(int*)CTL_NOW);
	putfonts8_asc(buf_back, binfo->scrnx, 10, 68, COL8_FFFFFF, s);
	sheet_refresh(sht_back, 0, 0, binfo->scrnx, 150); /* 刷新文字 */
	int flash = 0, nowSec = 0;
	sprintf(s, "A EIP:%d EAX:%d EBX:%d ESP:%d", tssa->eip, tssa->eax, tssa->ebx, tssa->esp);
	boxfill8(buf_back, binfo->scrnx, COL8_008484, 10, 180, binfo->scrnx, 200);
	putfonts8_asc(buf_back, binfo->scrnx, 10, 180, COL8_FFFFFF, s);
	sheet_refresh(sht_back, 10, 180, binfo->scrnx, 200); /* 刷新文字 */
	int change = 0;

	for (;;) {
		if (timeUsrCtl.count / 500 > nowSec)
		{
			nowSec = timeUsrCtl.count / 500;
			flash = !flash;
			if(flash)boxfill8(buf_back, binfo->scrnx, COL8_FFFFFF, 20, 200, 28, 216);
			else boxfill8(buf_back, binfo->scrnx, COL8_008484, 20, 200, 28, 216);
			sheet_refresh(sht_back, 20, 200, 28, 216);
		}
		count++; /* 从这里开始 */
		sprintf(s, "%010d", count);
		boxfill8(buf_win, 160, COL8_C6C6C6, 40, 28, 119, 43);
		putfonts8_asc(buf_win, 160, 40, 28, COL8_000000, s);
		sheet_refresh(sht_win, 40, 28, 120, 44); /* 到这里结束 */

		//secNow++;
		boxfill8(buf_back, binfo->scrnx, COL8_008484, 10, 85, 320, 120);
		sprintf(s, "timeNow:%dms", timeUsrCtl.count);
		putfonts8_asc(buf_back, binfo->scrnx, 10, 85, COL8_FFFFFF, s);
		sheet_refresh(sht_back, 10, 85, 320, 120); /* 刷新文字 */

		io_cli();
		if (fifo8_status(&keyfifo) + fifo8_status(&mousefifo) + fifo8_status(&for1) == 0)
		{
			io_sti(); /* 不做HLT */
		} 
		else
		{
			if (fifo8_status(&keyfifo) != 0)
			{
				i = fifo8_get(&keyfifo);
				io_sti();
				sprintf(s, "%02X", i);
				boxfill8(buf_back, binfo->scrnx, COL8_008484,  0, 16, 15, 31);
				putfonts8_asc(buf_back, binfo->scrnx, 0, 16, COL8_FFFFFF, s);
				sheet_refresh(sht_back, 0, 16, 16, 32); /* 刷新文字 */
			}
			else if (fifo8_status(&for1))
			{
				fifo8_get(&for1);
				io_sti();
				//
				//char tmp[100];
				//char d = fifo8_get(&for1);
				//sprintf(tmp, "d%cc", 'c');
				//boxfill8(buf_back, binfo->scrnx, COL8_008484, 20, 180, 52, 196);
				//putfonts8_asc(buf_back, binfo->scrnx, 20, 180, COL8_FFFFFF, tmp);
				//sheet_refresh(sht_back, 20, 180, 52, 196); /* 刷新文字 */
			}
			else if (fifo8_status(&mousefifo) != 0)
			{
				i = fifo8_get(&mousefifo);
				io_sti();
				if (mouse_decode(&mdec, i) != 0) 
				{
					/* 3字节都凑齐了，所以把它们显示出来*/
					sprintf(s, "[lcr %4d %4d]", mdec.x, mdec.y);
					if ((mdec.btn & 0x01) != 0) {
						s[1] = 'L';
					}
					if ((mdec.btn & 0x02) != 0) {
						s[3] = 'R';
					}
					if ((mdec.btn & 0x04) != 0) {
						s[2] = 'C';
					}
					boxfill8(buf_back, binfo->scrnx, COL8_008484, 32, 16, 32 + 15 * 8 - 1, 31);
					putfonts8_asc(buf_back, binfo->scrnx, 32, 16, COL8_FFFFFF, s);
					sheet_refresh(sht_back, 32, 16, 32 + 15 * 8, 32);  /* 刷新文字 */
					/* 移动光标 */
					mx += mdec.x;
					my += mdec.y;
					if (mx < 0) {
						mx = 0;
					}
					if (my < 0) {
						my = 0;
					}
					if (mx > binfo->scrnx - 1) {
						mx = binfo->scrnx - 1;
					}
					if (my > binfo->scrny - 1) {
						my = binfo->scrny - 1;
					}
					sprintf(s, "(%3d, %3d)", mx, my);
					boxfill8(buf_back, binfo->scrnx, COL8_008484, 0, 0, 79, 15); /* 消坐标 */
					putfonts8_asc(buf_back, binfo->scrnx, 0, 0, COL8_FFFFFF, s); /* 写坐标 */
					sheet_refresh(sht_back, 0, 0, 80, 16); /* 刷新文字 */
					sheet_slide(sht_mouse, mx, my); /* 包含sheet_refresh含sheet_refresh */
				}
			}
		}
		io_sti();
		far_jump(0, 4 * 8);
		sprintf(s, "A EIP:%d EAX:%d EBX:%d ESP:%d", tssa->eip, tssa->eax, tssa->ebx, tssa->esp);
		boxfill8(buf_back, binfo->scrnx, COL8_008484, 10, 200, binfo->scrnx, 220);
		putfonts8_asc(buf_back, binfo->scrnx, 10, 200, COL8_FFFFFF, s);
		sheet_refresh(sht_back, 10, 200, binfo->scrnx, 220); /* 刷新文字 */

	}
}


void make_window8(unsigned char* buf, int xsize, int ysize, char* title)
{
	static char closebtn[14][16] = {
		"OOOOOOOOOOOOOOO@",
		"OQQQQQQQQQQQQQ$@",
		"OQQQQQQQQQQQQQ$@",
		"OQQQ@@QQQQ@@QQ$@",
		"OQQQQ@@QQ@@QQQ$@",
		"OQQQQQ@@@@QQQQ$@",
		"OQQQQQQ@@QQQQQ$@",
		"OQQQQQ@@@@QQQQ$@",
		"OQQQQ@@QQ@@QQQ$@",
		"OQQQ@@QQQQ@@QQ$@",
		"OQQQQQQQQQQQQQ$@",
		"OQQQQQQQQQQQQQ$@",
		"O$$$$$$$$$$$$$$@",
		"@@@@@@@@@@@@@@@@"
	};

	int x, y;
	char c;
	boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, xsize - 1, 0);
	boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, xsize - 2, 1);
	boxfill8(buf, xsize, COL8_C6C6C6, 0, 0, 0, ysize - 1);
	boxfill8(buf, xsize, COL8_FFFFFF, 1, 1, 1, ysize - 2);
	boxfill8(buf, xsize, COL8_848484, xsize - 2, 1, xsize - 2, ysize - 2);
	boxfill8(buf, xsize, COL8_000000, xsize - 1, 0, xsize - 1, ysize - 1);
	boxfill8(buf, xsize, COL8_C6C6C6, 2, 2, xsize - 3, ysize - 3);
	boxfill8(buf, xsize, COL8_000084, 3, 3, xsize - 4, 20);
	boxfill8(buf, xsize, COL8_848484, 1, ysize - 2, xsize - 2, ysize - 2);
	boxfill8(buf, xsize, COL8_000000, 0, ysize - 1, xsize - 1, ysize - 1);
	putfonts8_asc(buf, xsize, 24, 4, COL8_FFFFFF, title);

	for (y = 0; y < 14; y++) {
		for (x = 0; x < 16; x++) {
			c = closebtn[y][x];
			if (c == '@') {
				c = COL8_000000;
			}
			else if (c == '$') {
				c = COL8_848484;
			}
			else if (c == 'Q') {
				c = COL8_C6C6C6;
			}
			else {
				c = COL8_FFFFFF;
			}
			buf[(5 + y) * xsize + (xsize - 21 + x)] = c;
		}
	}
	return;
}
